#ifndef SOCKET_MAMANGER_H_
#define SOCKET_MAMANGER_H_

#include <ctime>
#include <chrono>
#include <string>
#include <map>

struct event_base;
struct event;
struct bufferevent;
class WorkThread;
class Metadata;

namespace sec
{
class MsgHeader;
}

/// @brief 客户端连接管理.
/// 对每一条socket建立bufferevent进行消息处理
class SocketManager
{
public:
    /// @brief 构造函数
    /// @param thread 当前工作线程
    /// @param ev_base 事件循环
    /// @param socket 客户端连接套接字
    /// @param timeout 超时时间
    SocketManager(WorkThread *thread, event_base *ev_base, int socket, int timeout = 10);
    /// @brief 初始化
    bool Init();
    virtual ~SocketManager();
    /// @brief 消息读取回调
    void ReadCb();
    /// @brief 消息写入回调
    void WriteCb();
    /// @brief 事件回调
    void EventCb(short event);
    /// @brief 消息总线读取回调
    /// @param meta 元数据
    void ReadFromNetBus(Metadata *meta);
    /// @brief 发送消息到客户端的封装函数
    /// @param header 消息头
    /// @param header_size 消息头大小
    /// @param data 数据
    /// @param data_size 数据大小
    bool SendMessage(const char *header, int header_size, const char *data, int data_size); // send msg to client

private:
    void RecvConnectReqest(sec::MsgHeader *header, const char *data, int data_size);
    /// @brief 接收和处理登录请求
    /// @param header 消息头
    /// @param data 消息体
    /// @param data_size 消息体大小
    void RecvLoginRequest(sec::MsgHeader *header, const char *data, int data_size); // client login handle
    /// @brief 接收心跳
    /// @param data
    /// @param data_size
    void RecvHeartBeat(const char *data, int data_size); // client sent to heart-beat with keeping connection
    /// @brief 接收用户信息查询请求
    /// @param header
    /// @param data
    /// @param data_size
    void RecvUserInfoRequest(sec::MsgHeader *header, const char *data, int data_size); // client user info handle
    /// @brief 接收用户状态查询请求
    /// @param header
    /// @param data
    /// @param data_size
    void RecvUserStatusRequest(sec::MsgHeader *header, const char *data, int data_size); // user status list handle
	/// @brief 接收服务注册
    /// @param header
    /// @param data
    /// @param data_size
    void RecvServiceRegist(sec::MsgHeader *header, const char *data, int data_size);

    /// @brief 获得当前时间戳
    std::time_t GetTimestamp();
    event_base *ev_base_ = nullptr;
    int socket_ = 0;
    bufferevent *buff_ev_ = nullptr;
    int timeout_ = 0;
    WorkThread *work_thread_ = nullptr;
    std::string token_ = "";    // 用户令牌
    unsigned int user_id_ = 0;  // 用户id
    std::string username_ = ""; // username
    std::string alias_ = "";    // alias
};

#endif